﻿using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace StockDetective
{
    public partial class StockChart : Form
    {
        //使用rootpath调整数据储存位置 2017/1/2qdh
        private const string stockdatapath = @"C:\data\stockdata\";//@"..\..\Data\StockData\";
        private const string MarketCodeForSH = "SH999999";
        private const string MarketCodeForSZ = "SZ399001";
        /// <summary>   生成某支股票某一天的分时图
        /// </summary>
        /// <param name="date"></param>
        /// <param name="code"></param>
        public StockChart(string date, string code)
        {
            InitializeComponent();
            NewCSVForChart(date, code);
            DisplayChart(date, code);
        }
        /// <summary>   生成新的适合作图的csv；
        /// 如果适合作图的csv存在，则会覆盖
        /// </summary>
        /// <param name="date"></param>
        /// <param name="id"></param>
        private void NewCSVForChart(string date, string id)
        {
            //筛选目录下的201610**的文件夹
            string filesPath = /*@"..\..\Data\StockData\"*/ stockdatapath + date.Substring(0, 6);
            DirectoryInfo allFolder = new DirectoryInfo(filesPath);
            DirectoryInfo[] dirInfo = allFolder.GetDirectories();

            //遍历文件夹
            foreach (DirectoryInfo eachFolder in dirInfo)
            {
                if (eachFolder.Name == date)
                {
                    FileInfo[] fileInfo = eachFolder.GetFiles();
                    foreach (FileInfo NextFile in fileInfo)
                    {
                        if (NextFile.Name == id + ".csv")
                        {
                            //把csv文件存到Datatable
                            DataTable dt = new DataTable();
                            DataTable dt2 = new DataTable();
                            dt2.Columns.Add("编码", typeof(string));
                            dt2.Columns.Add("金额", typeof(decimal));
                            dt2.Columns.Add("代码", typeof(string));
                            dt2.Columns.Add("数量", typeof(int));
                            dt = OpenCSVForNew(NextFile.FullName);

                            //生成dt2
                            var vardt = from p in dt.AsEnumerable()
                                        let code = p.Field<string>("编码").Substring(0, p.Field<string>("编码").Length - 2)
                                        group p by new { t1 = code, t2 = p.Field<string>("代码") } into g
                                        let count = g.Count()
                                        select new
                                        {
                                            Code = g.Key.t1,
                                            金额 = Math.Round(g.Sum(x => x.Field<decimal>("金额")) / count, 2,
                                            MidpointRounding.AwayFromZero),
                                            代码 = g.Key.t2,
                                            Sum = g.Sum(x => x.Field<int>("数量"))
                                        };

                            foreach (var outputvar in vardt)
                            {
                                DataRow dr = dt2.NewRow();
                                dr["编码"] = outputvar.Code;
                                dr["金额"] = outputvar.金额;
                                dr["代码"] = outputvar.代码;
                                dr["数量"] = outputvar.Sum;
                                dt2.Rows.Add(dr);
                            }
                            //把新的Datatable保存到csv文件
                            CSV.SaveCSV(dt2, eachFolder.FullName + "\\" + NextFile.Name.Substring(0, 8) + "[2].csv");
                        }
                    }
                }
            }
        }
        /// <summary>   为生成新的适合作图的csv而写的csv读取函数
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static DataTable OpenCSVForNew(string filePath)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("编码", typeof(string));
            dt.Columns.Add("金额", typeof(decimal));
            dt.Columns.Add("代码", typeof(string));
            dt.Columns.Add("数量", typeof(int));
            var lines = File.ReadAllLines(filePath).Select(s => s.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries));
            foreach (var line in lines)
            {
                dt.Rows.Add(line);
            }
            return dt;
        }
        /// <summary>   显示分时图
        /// </summary>
        /// <param name="date"></param>
        /// <param name="code"></param>
        private void DisplayChart(string date, string code)
        {
            #region 读取CSV到dt
            //  路径从Debug里的exe所处位置开始算起，故返回上级目录两次
            string filePath = /*@"..\..\Data\StockData\"*/ stockdatapath + date.Substring(0, 6) + @"\" + date + @"\" + code + "[2].csv";
            DataTable dt = new DataTable();
            dt = CSV.OpenCSV(filePath);
            //  转换第一列为 (H)H:MM:SS 时间格式
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                string origin = dt.Rows[i][0].ToString();
                string tmp = "";
                if (origin.Substring(0, 1) == "9")
                    tmp = origin.Substring(0, 1) + ":" + origin.Substring(1, 2);
                else if (origin.Substring(0, 2) == "10" || origin.Substring(0, 2) == "11")
                    tmp = origin.Substring(0, 2) + ":" + origin.Substring(2, 2);
                else
                {
                    if (System.Convert.ToInt32(origin.Substring(2, 2)) < 30)
                        tmp = (System.Convert.ToInt32(origin.Substring(0, 2)) - 2).ToString() + ":" +
                                (System.Convert.ToInt32(origin.Substring(2, 2)) + 30).ToString();
                    else if (System.Convert.ToInt32(origin.Substring(2, 2)) > 30)
                        tmp = (System.Convert.ToInt32(origin.Substring(0, 2)) - 1).ToString() + ":" +
                                (System.Convert.ToInt32(origin.Substring(2, 2)) - 30).ToString();
                    else
                        tmp = (System.Convert.ToInt32(origin.Substring(0, 2)) - 1).ToString() + ":00";
                }
                dt.Rows[i][0] = tmp;
            }
            #endregion

            #region 用CustomLabel搭建x轴
            CustomLabel label1 = new CustomLabel();
            CustomLabel label2 = new CustomLabel();
            CustomLabel label3 = new CustomLabel();
            CustomLabel label4 = new CustomLabel();
            CustomLabel label5 = new CustomLabel();
            CustomLabel label6 = new CustomLabel();
            CustomLabel label7 = new CustomLabel();
            CustomLabel label8 = new CustomLabel();
            CustomLabel label9 = new CustomLabel();
            CustomLabel[] lables = { label1, label2, label3, label4, label5, label6, label7, label8, label9 };
            label1.Text = "9:30";
            label2.Text = "10:00";
            label3.Text = "10:30";
            label4.Text = "11:00";
            label5.Text = "11:30";
            label6.Text = "13:30";
            label7.Text = "14:00";
            label8.Text = "14:30";
            label9.Text = "15:00";
            for (int i = 0; i < 9; i++)
            {
                lables[i].ToPosition = 0.7915 + 0.0415 * i;
                chart.ChartAreas.FindByName("Price").AxisX.CustomLabels.Add(lables[i]);
                chart.ChartAreas.FindByName("Volumn").AxisX.CustomLabels.Add(lables[i]);
            }
            #endregion

            #region 买入价的dt, series
            DataTable dtForBuyingPrice = new DataTable();
            dtForBuyingPrice.Columns.Add("Time", typeof(DateTime));
            dtForBuyingPrice.Columns.Add("BuyingPrice", typeof(double));
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i][2].ToString() == "B")
                {
                    dtForBuyingPrice.Rows.Add();
                    for (int j = 0; j < 2; j++)
                        dtForBuyingPrice.Rows[dtForBuyingPrice.Rows.Count - 1][j] = dt.Rows[i][j];
                }
            }
            Series srForBuyingPrice = this.chart.Series.FindByName("BuyingPrice");
            srForBuyingPrice.Points.DataBind(dtForBuyingPrice.AsEnumerable(), "Time", "BuyingPrice", "");
            srForBuyingPrice.XValueType = ChartValueType.Time;

            //label.GridTicks = GridTickTypes.Gridline;
            #endregion

            #region 卖出价的dt, series
            DataTable dtForSalePrice = new DataTable();
            dtForSalePrice.Columns.Add("Time", typeof(DateTime));
            dtForSalePrice.Columns.Add("SalePrice", typeof(double));
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i][2].ToString() == "S")
                {
                    dtForSalePrice.Rows.Add();
                    for (int j = 0; j < 2; j++)
                        dtForSalePrice.Rows[dtForSalePrice.Rows.Count - 1][j] = dt.Rows[i][j];
                }
            }
            Series srForSalePrice = this.chart.Series.FindByName("SalePrice");
            srForSalePrice.Points.DataBind(dtForSalePrice.AsEnumerable(), "Time", "SalePrice", "");
            srForSalePrice.XValueType = ChartValueType.Time;
            #endregion

            #region 成交量的dt,series   （暂时移除）
            //DataTable dtForVolumn = new DataTable();
            //dtForVolumn.Columns.Add("Time", typeof(DateTime));
            //dtForVolumn.Columns.Add("Volumn", typeof(int));
            ///*
            // * 没有考虑只有买或只有卖的情况   (待修改）
            // */
            //for (int i = 0; i < dt.Rows.Count - 1; i = i + 2)
            //{
            //    dtForVolumn.Rows.Add();
            //    dtForVolumn.Rows[dtForVolumn.Rows.Count - 1][0] = dt.Rows[i][0];
            //    dtForVolumn.Rows[dtForVolumn.Rows.Count - 1][1] = System.Convert.ToInt32(dt.Rows[i][3]) + System.Convert.ToInt32(dt.Rows[i + 1][3]);
            //}
            //Series srForVolumn = this.chart.Series.FindByName("Volumn");
            //srForVolumn.Points.DataBind(dtForVolumn.AsEnumerable(), "Time", "Volumn", "");
            //srForVolumn.XValueType = ChartValueType.Time;
            #endregion

            #region 买入量的dt,series
            DataTable dtForBuy = new DataTable();
            dtForBuy.Columns.Add("Time", typeof(DateTime));
            dtForBuy.Columns.Add("BuyingVolumn", typeof(int));
            int count = 0;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i][2].ToString() == "B")
                {
                    dtForBuy.Rows.Add();
                    dtForBuy.Rows[i - count][0] = dt.Rows[i][0];
                    dtForBuy.Rows[i - count][1] = dt.Rows[i][3];
                }
                else
                    count++;
            }
            count = 0;
            Series srForBuy = this.chart.Series.FindByName("BuyingVolumn");
            srForBuy.Points.DataBind(dtForBuy.AsEnumerable(), "Time", "BuyingVolumn", "");
            srForBuy.XValueType = ChartValueType.Time;
            #endregion

            #region 卖出量的dt,series
            DataTable dtForSale = new DataTable();
            dtForSale.Columns.Add("Time", typeof(DateTime));
            dtForSale.Columns.Add("SaleVolumn", typeof(int));
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i][2].ToString() == "S")
                {
                    dtForSale.Rows.Add();
                    dtForSale.Rows[i - count][0] = dt.Rows[i][0];
                    dtForSale.Rows[i - count][1] = 0 - System.Convert.ToInt32(dt.Rows[i][3]);
                }
                else
                    count++;
            }
            count = 0;
            Series srForSale = this.chart.Series.FindByName("SaleVolumn");
            srForSale.Points.DataBind(dtForSale.AsEnumerable(), "Time", "SaleVolumn", "");
            srForSale.XValueType = ChartValueType.Time;
            #endregion

            #region 显示大盘
            DisplayChart_Market(date, code);
            #endregion
        }
        /// <summary>   显示分时图函数中的显示大盘
        /// 
        /// </summary>
        /// <param name="date"></param>
        /// <param name="code"></param>
        private void DisplayChart_Market(string date, string code)
        {
            string filePathForMarket = "";
            if (code.Substring(0, 2) == "SH")
                filePathForMarket = /*@"..\..\Data\StockData\"*/ stockdatapath + date.Substring(0, 6) + @"\" + date + @"\" + MarketCodeForSH + ".csv";
            else if (code.Substring(0, 2) == "SZ")
                filePathForMarket = /*@"..\..\Data\StockData\"*/ stockdatapath + date.Substring(0, 6) + @"\" + date + @"\" + MarketCodeForSZ + ".csv";
            DataTable dt2 = CSV.OpenCSV(filePathForMarket);
            for (int i = 0; i < dt2.Rows.Count; i++)
            {
                string origin = dt2.Rows[i][0].ToString();
                string tmp = "";
                if (origin.Substring(0, 1) == "9")
                    tmp = origin.Substring(0, 1) + ":" + origin.Substring(1, 2);
                else if (origin.Substring(0, 2) == "10" || origin.Substring(0, 2) == "11")
                    tmp = origin.Substring(0, 2) + ":" + origin.Substring(2, 2);
                else
                {
                    if (System.Convert.ToInt32(origin.Substring(2, 2)) < 30)
                        tmp = (System.Convert.ToInt32(origin.Substring(0, 2)) - 2).ToString() + ":" +
                                (System.Convert.ToInt32(origin.Substring(2, 2)) + 30).ToString();
                    else if (System.Convert.ToInt32(origin.Substring(2, 2)) > 30)
                        tmp = (System.Convert.ToInt32(origin.Substring(0, 2)) - 1).ToString() + ":" +
                                (System.Convert.ToInt32(origin.Substring(2, 2)) - 30).ToString();
                    else
                        tmp = (System.Convert.ToInt32(origin.Substring(0, 2)) - 1).ToString() + ":00";
                }
                dt2.Rows[i][0] = tmp;
            }
            DataTable dtForMarket = new DataTable();
            dtForMarket.Columns.Add("Time", typeof(DateTime));
            dtForMarket.Columns.Add("MarketIndex", typeof(double));
            for (int i = 0; i < dt2.Rows.Count; i++)
            {
                dtForMarket.Rows.Add();
                for (int j = 0; j < 2; j++)
                    dtForMarket.Rows[i][j] = dt2.Rows[i][j];
            }
            Series srForMarket = this.chart.Series.FindByName("MarketIndex");
            srForMarket.Points.DataBind(dtForMarket.AsEnumerable(), "Time", "MarketIndex", "");
            srForMarket.XValueType = ChartValueType.Time;
        }
    }
}
